package work.linruchang.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.hash.Hash;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 增强的容器处理工具
 *
 * @author LinRuChang
 * @version 1.0
 * @date 2021/04/23
 * @since 1.8
 **/
public class EnhanceCollUtil extends CollUtil {

    /**
     * 表格式打印 列左对齐
     *
     * @param elems 容器
     * @return
     */
    public static String tableFormat(List<List<String>> elems) {
        elems = CollUtil.emptyIfNull(elems);

        // 最大单元格长度
        Integer maxCellLength = elems.stream()
                .map(elemList -> CollUtil.emptyIfNull(elemList).stream()
                        .map(StrUtil::length)
                        .collect(Collectors.toList())
                )
                .flatMap(Collection::stream)
                .max(Integer::compare)
                .orElse(0);

        if (maxCellLength < 1) {
            return null;
        }

        // Stirng格式化的时候固定长度
        Integer stringFormatFixedLength = maxCellLength + 2;


        List<String> firstRowList = CollUtil.getFirst(elems);
        Map<Integer, Integer> firstRowChineseCountMap = MapUtil.newHashMap();
        for (int j = 0; j < CollUtil.size(firstRowList); j++) {
            String s = firstRowList.get(j);
            firstRowChineseCountMap.put(j, EnhanceStrUtil.chineseCount(s));
        }


        List<String> rows = CollUtil.newArrayList();

        for (int i = 0; i < CollUtil.size(elems); i++) {
            List<String> row = CollUtil.get(elems, i);
            String rowFormat = rowFormatBuild(row, stringFormatFixedLength, firstRowChineseCountMap);
            rows.add(String.format(rowFormat, row.toArray()));
        }

        return CollUtil.join(rows, "\n");
    }

    /**
     * 行格式化参数
     *
     * @param row                         行
     * @param cellFixLength               单元格固定的长度
     * @param firstRowCellChineseCountMap 首行每个单元格的中文字符数
     * @return
     */
    public static String rowFormatBuild(List<String> row, Integer cellFixLength, Map<Integer, Integer> firstRowCellChineseCountMap) {
        cellFixLength = Convert.toInt(cellFixLength, 0);

        StringBuilder resultSB = new StringBuilder();
        for (int i = 0; i < CollUtil.size(row); i++) {
            String currentCell = CollUtil.get(row, i);
            resultSB.append(formatBuild(cellFixLength, MapUtil.getInt(firstRowCellChineseCountMap, i, 0), EnhanceStrUtil.chineseCount(currentCell)));
        }
        return resultSB.toString();
    }


    private static String formatBuild(Integer fixLength) {
        return StrUtil.format("%-{}s", fixLength);
    }

    /**
     * @param fixLength                               固定长度
     * @param firstRowCurrentColumnCellChineseCount   首行当前列的中文字数量
     * @param currentRowCurrentColumnCellChineseCount 当前行当前列的中文字数量
     * @return
     */
    private static String formatBuild(Integer fixLength, Integer firstRowCurrentColumnCellChineseCount, Integer currentRowCurrentColumnCellChineseCount) {
        int differenceValue = firstRowCurrentColumnCellChineseCount - currentRowCurrentColumnCellChineseCount;
        fixLength += differenceValue;
        return formatBuild(fixLength);
    }


    /**
     * 过滤value是blank的键值对，不会在源容器上进行剔除，返回结果是新的Map
     *
     * @param sourceMap
     * @return
     */
    public static <K, V> Map<K, V> filterBlankValue(Map<K, V> sourceMap) {
        Map result = MapUtil.filter(sourceMap, new Filter<Map.Entry<K, V>>() {
            @Override
            public boolean accept(Map.Entry<K, V> entry) {
                Object value = entry.getValue();
                if (value != null && StrUtil.isNotBlank(value.toString())) {
                    return true;
                } else {
                    return false;
                }
            }
        });
        return result;
    }

    public static <T> List<T> getFieldValuesByType(Iterable<?> collection, final String fieldName, Class<T> fieldType, boolean ignoreNull) {
        List<Object> fieldValues = getFieldValues(collection, fieldName, ignoreNull);
        ArrayList<T> result = new ArrayList<>();
        if (isNotEmpty(collection)) {
            for (Object elem : fieldValues) {
                result.add(EnhanceTypeUtil.convertValue(fieldType, elem));
            }
        }
        return result;
    }

    /**
     * 目标collection容器null则转换成空容器
     *
     * @param collection
     * @return
     */
    public static <T> Collection<T> nullToEmpty(Collection<T> collection) {
        return collection == null ? (List<T>) Collections.emptyList() : collection;
    }

    /**
     * 目标list容器null则转换成空容器
     *
     * @param list
     * @return
     */
    public static <T> List<T> nullToEmpty(List<T> list) {
        return list == null ? (List<T>) Collections.emptyList() : list;
    }


    /**
     * 将源集合元素sourceDatas拆分为N个最大容量为splitCollectionMaxSize的集合
     *
     * @param sourceDatas            需要的拆分的容器
     * @param splitCollectionMaxSize 拆分后每个容器的最大容量
     * @param <T>
     * @return
     */
    public static <T> Collection<Collection<T>> splitCollections(Collection<T> sourceDatas, int splitCollectionMaxSize) {
        Assert.notNull(sourceDatas);
        int sourceDatasSize = sourceDatas.size();
        EnhanceAssert.checkBetween(splitCollectionMaxSize, 1, null);
        int resultCollSize = sourceDatasSize % splitCollectionMaxSize == 0 ? sourceDatasSize / splitCollectionMaxSize : sourceDatasSize / splitCollectionMaxSize + 1;
        Collection result = new ArrayList(sourceDatasSize / splitCollectionMaxSize + 1);
        Iterator<T> iterator = sourceDatas.iterator();
        for (int i = 0; i < resultCollSize; i++) {
            ArrayList<T> resultElementCollection = new ArrayList<>(splitCollectionMaxSize);
            if (i != resultCollSize - 1) {
                for (int j = 0; j < splitCollectionMaxSize; j++) {
                    resultElementCollection.add(iterator.next());
                }
            } else {
                while (iterator.hasNext()) {
                    resultElementCollection.add(iterator.next());
                }
            }
            result.add(resultElementCollection);
        }
        return result;
    }


    /**
     * 根据filter，如果找到任何一个元素则返回true，否则false
     *
     * @param collection
     * @param filter     true则符合 false不符合
     * @return
     */
    public static <T> boolean anyMatch(Collection<T> collection, Filter<T> filter) {
        Assert.notNull(filter);
        boolean matchFlag = false;
        if (isNotEmpty(collection)) {
            T one = findOne(collection, filter);
            if (one != null) {
                matchFlag = true;
            }
        }
        return matchFlag;
    }

    /**
     * map转成字符串
     * value如果是数组类型会使用Arrays.toString进行打印出来
     *
     * @param map map类型
     * @return
     */
    public static String toString(Map map) {
        if (map == null) {
            return null;
        } else {
            Set<Map.Entry<Object, Object>> entries = map.entrySet();
            Iterator<Map.Entry<Object, Object>> i = entries.iterator();
            StringBuilder sb = new StringBuilder();
            sb.append('{');
            for (; ; ) {
                if (!i.hasNext()) {
                    sb.append('}').toString();
                    break;
                }
                Map.Entry<Object, Object> next = i.next();
                Object key = next.getKey();
                Object value = next.getValue();
                sb.append(key);
                sb.append('=');
                sb.append(ArrayUtil.isArray(value) ? EnhanceArrayUtil.toString(value) : value);
                sb.append(',').append(' ');
            }
            if (StrUtil.length(sb) > 2 && sb.lastIndexOf(",") == sb.length() - 3) {
                sb.replace(sb.length() - 3, sb.length() - 1, "");
            }
            return sb.toString();
        }
    }

    /**
     * 过滤元素，不会影响入参的容器对象
     *
     * @param collection
     * @param filter
     * @param <T>
     * @return
     */
    @Deprecated
    public static <T> List<T> filter2(List<T> collection, Filter<T> filter) {
        List<T> targetList = nullToEmpty(collection);
        List<T> resultList = new ArrayList<>();
        for (T elem : targetList) {
            if (filter.accept(elem)) {
                resultList.add(elem);
            }
        }
        return resultList;
    }


    /**
     * 过滤元素，不会影响入参的容器对象
     *
     * @param list
     * @param editor
     * @param <T>
     * @return null则返回Collections.emptyList()
     */
    // public static <T> List<T> filter(List<T> list, Editor<T> editor) {
    //    return nullToEmpty(CollUtil.filter(list, editor));
    //}

    /**
     * 获取给定Bean列表中指定字段名对应字段值的列表<br>
     * 列表元素支持Bean与Map
     *
     * @param collection Bean集合或Map集合
     * @param fieldName  字段名或map的键
     * @param fieldClazz 没啥作用，仅是用来标识fieldName属性的类型，方便结果返回是Long元素
     * @param ignoreNull 是否忽略值为{@code null}的字段
     * @return 字段值列表
     * @since 4.5.7
     */
    public static <T> List<T> getFieldValues(Iterable<?> collection, final String fieldName, final Class<T> fieldClazz, boolean ignoreNull) {
        List<Object> fieldValues = nullToEmpty(getFieldValues(collection, fieldName, ignoreNull));
        ArrayList<T> result = new ArrayList<>();
        for (Object fieldValue : fieldValues) {
            result.add((T) fieldValue);
        }
        return result;
    }


    /**
     * 分组
     *
     * @param collection   需要分组的原容器
     * @param hashFunction 根据容器里面的每个元素的hash值进行分组，相同且在同一组
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> group(Collection<T> collection, final Hash<T> hashFunction) {
        Assert.notNull(hashFunction);
        collection = nullToEmpty(collection);
        final List<List<T>> result = new ArrayList<>();
        final HashMap<Integer, List<T>> hashToListMap = new HashMap<>();
        forEach(collection.iterator(), new Consumer<T>() {
            @Override
            public void accept(T value, int index) {
                int hash = hashFunction.hash(value).intValue();
                if (hashToListMap.containsKey(hash)) {
                    hashToListMap.get(hash).add(value);
                } else {
                    ArrayList<T> initColl = new ArrayList<>();
                    initColl.add(value);
                    hashToListMap.put(hash, initColl);
                }
            }
        });

        forEach(hashToListMap.entrySet().iterator(), new Consumer<Map.Entry<Integer, List<T>>>() {
            @Override
            public void accept(Map.Entry<Integer, List<T>> entry, int index) {
                result.add(entry.getValue());
            }
        });

        return result;
    }

    /**
     * 添加元素,在sourceList上添加元素
     * 并集
     *
     * @param sourceList
     * @param newList
     * @return 返回sourceList
     */
    public static <T> List<T> addElements(List<T> sourceList, List<T> newList) {
        if (sourceList == null) {
            sourceList = new ArrayList<>();
        }
        if (isNotEmpty(newList)) {
            sourceList.addAll(newList);
        }
        return sourceList;
    }


    /**
     * 并集 == 根据插入顺序
     *
     * @param containers
     * @param <T>
     * @return
     */
    public static <T> List<T> unionInsertSequence(Collection<T>... containers) {
        if (ArrayUtil.isEmpty(containers)) {
            return Collections.emptyList();
        } else {
            List<T> result = new ArrayList<>();
            for (Collection container : containers) {
                if (isNotEmpty(container)) {
                    result.addAll(container);
                }
            }
            return result;
        }
    }

    /**
     * 查找t是否在containers容器中找到，找到的准则是comparator比较器结果等于0
     *
     * @param containers
     * @param t
     * @param comparator
     * @return
     */
    public static <T> boolean hasElement(Collection<T> containers, final T t, final Comparator<T> comparator) {
        T findElement = CollUtil.findOne(containers, new Filter<T>() {
            @Override
            public boolean accept(T containerElement) {
                if (comparator != null) {
                    return comparator.compare(containerElement, t) == 0;
                } else {
                    return ObjectUtil.equal(containerElement, t);
                }
            }
        });
        return findElement != null;
    }

    /**
     * 去重
     *
     * @param containers 容器
     * @param comparator 容器元素的比较器
     * @param <T>
     * @return
     */
    public static <T> List<T> distinct(Collection<T> containers, Comparator<T> comparator) {
        if (ObjectUtil.hasEmpty(containers, comparator)) {
            return distinct(containers);
        } else {
            containers = CollUtil.isNotEmpty(containers) ? containers : Collections.<T>emptyList();
            List<T> result = new ArrayList<>();
            for (T t : containers) {
                if (!hasElement(result, t, comparator)) {
                    result.add(t);
                }
            }
            return result;
        }
    }


    /**
     * 将value变成key，key变成Value使用容器进行存储
     *
     * @param targetMap
     * @param <T>
     * @param <M>
     * @return
     */
    public static <T, M> Map<M, List<T>> valueToKey(Map<T, M> targetMap) {
        if (CollUtil.isEmpty(targetMap)) {
            return Collections.emptyMap();
        } else {
            final Map result = new HashMap();
            CollUtil.forEach(targetMap, new KVConsumer<T, M>() {
                @Override
                public void accept(T key, M value, int index) {
                    List<T> resultMapValue = (List<T>) result.get(value);
                    if (resultMapValue == null) {
                        resultMapValue = new ArrayList<>();
                    }
                    resultMapValue.add(key);
                    result.put(value, resultMapValue);
                }
            });
            return result;
        }
    }


    /**
     * 在elems中，每个元素的elemFieldName有多少个与needMatchValue匹配的
     *
     * @param elems           容器
     * @param elemFieldNames  需要匹配的元素字段  【值会进行 分割符进行分割】
     * @param delimiter       字段值得分割符， 空则使用默认分割符逗号
     * @param needMatchValues 需要匹配的字段值
     * @param <T>
     * @return
     */
    public static <T> Map<T, Integer> matchedFieldsValueNumberMap(Collection<T> elems, Collection<String> elemFieldNames, String delimiter, Collection<String> needMatchValues) {
        //===============过滤空元素===================
        elems = CollUtil.filter(elems, new Filter<T>() {
            @Override
            public boolean accept(T t) {
                return ObjectUtil.isNotEmpty(t);
            }
        });
        elemFieldNames = CollUtil.filter(elemFieldNames, new Filter<String>() {
            @Override
            public boolean accept(String fieldName) {
                return ObjectUtil.isNotEmpty(fieldName);
            }
        });
        needMatchValues = CollUtil.filter(needMatchValues, new Filter<String>() {
            @Override
            public boolean accept(String needMatchValue) {
                return ObjectUtil.isNotEmpty(needMatchValue);
            }
        });
        //===============过滤空元素===================
        delimiter = StrUtil.blankToDefault(delimiter, StrUtil.COMMA);
        Map<T, Integer> result = Collections.emptyMap();
        if (ObjectUtil.isAllNotEmpty(elems, elemFieldNames, needMatchValues)) {
            result = new HashMap<>();
            for (T elem : elems) {
                result.put(elem, 0);
                Set<String> elemFieldValue = new HashSet<>();
                for (String fieldName : elemFieldNames) {
                    Object fieldValue = ReflectUtil.getFieldValue(elem, fieldName);
                    if (ObjectUtil.isNotEmpty(fieldValue)) {
                        elemFieldValue.addAll(Arrays.asList(fieldValue.toString().split(delimiter)));
                    }
                }
                needMatchValues = new HashSet(needMatchValues);  // 去重
                for (String needMatchValue : needMatchValues) {
                    if (elemFieldValue.contains(needMatchValue)) {
                        result.put(elem, result.get(elem) + 1);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 在elems中，每个元素的elemFieldName有多少个与needMatchValue匹配的
     *
     * @param elems                  容器
     * @param elemFieldNames         需要匹配的元素字段  【值会进行 分割符进行分割】
     * @param bestMatchSortFieldName 如果找到同匹配数的元素则使用最大的排序的字段值进行获取结果
     * @param delimiter              字段值得分割符， 空则使用默认分割符逗号
     * @param needMatchValues        需要匹配的字段值
     * @return
     */
    public static <T> T bestMatchFieldElm(Collection<T> elems, Collection<String> elemFieldNames, final String bestMatchSortFieldName, String delimiter, Collection<String> needMatchValues) {
        T result = null;

        Map<T, Integer> matchInfo = matchedFieldsValueNumberMap(elems, elemFieldNames, delimiter, needMatchValues);
        Map<Integer, List<T>> reverseMatchInfo = valueToKey(matchInfo);

        Set<Integer> numbers = reverseMatchInfo.keySet();

        Integer max = EnhanceCollUtil.max(numbers);
        if (max != null && max > 0) {
            List<T> results = reverseMatchInfo.get(max);
            if (StrUtil.isNotBlank(bestMatchSortFieldName) && isNotEmpty(results)) {
                // 倒序
                results = CollUtil.sort(results, new Comparator<T>() {
                    @Override
                    public int compare(T result1, T result2) {
                        Object result1FieldValue = ReflectUtil.getFieldValue(result1, bestMatchSortFieldName);
                        Object result2FieldValue = ReflectUtil.getFieldValue(result2, bestMatchSortFieldName);
                        return -CompareUtil.compare(result1FieldValue, result2FieldValue, false);
                    }
                });
                result = results.get(0);
            }
        }
        return result;
    }

    /**
     * 取最大值 == 低版本的hutool有bug，故需重写兼容一下
     *
     * @param <T>  元素类型
     * @param coll 集合
     * @return 最大值
     * @see Collections#max(Collection)
     * @since 4.6.5
     */
    public static <T extends Comparable<? super T>> T max(Collection<T> coll) {
        T result = null;
        if (isNotEmpty(coll)) {
            result = Collections.max(coll);
        }
        return result;
    }

    /**
     * 加强{@link cn.hutool.core.collection.CollUtil#sort(List, Comparator)}防止空指针出现
     * <p>
     * 针对List排序，排序会修改原List
     *
     * @param <T>  元素类型
     * @param list 被排序的List
     * @param c    {@link Comparator}
     * @return 原list
     * @see Collections#sort(List, Comparator)
     */
    public static <T> List<T> sort(List<T> list, Comparator<? super T> c) {
        if (ObjectUtil.hasEmpty(list, c)) {
            return list;
        } else {
            return CollUtil.sort(list, c);
        }
    }


    /**
     * 线程安全的List
     *
     * @param collection
     * @param <T>
     * @return
     */
    public static <T> List<T> newSyncList(Collection<T> collection) {
        return Collections.synchronizedList(ListUtil.toList(collection));
    }

    /**
     * 线程安全的List
     *
     * @param <T>
     * @return
     */
    public static <T> List<T> newSyncList() {
        return newSyncList(null);
    }


    public static <T> String join(Iterable<T> iterable, CharSequence conjunction, Integer start, Integer end) {
        if (iterable == null) {
            return null;
        }
        start = ObjectUtil.defaultIfNull(start, 0);
        Assert.isTrue(CompareUtil.compare(start, end, true) < 0);
        Assert.isTrue(CompareUtil.compare(start, 0) >= 0);
        Assert.isTrue(end == null || CompareUtil.compare(end, CollUtil.size(iterable)) <= 0);
        Assert.isTrue(CompareUtil.compare(start, CollUtil.size(iterable) - 1) <= 0);


        iterable = ObjectUtil.defaultIfNull(iterable, CollUtil.newArrayList());

        int currentIndex = 0;
        List<T> subContainers = CollUtil.newArrayList();

        for (T elem : iterable) {

            if (end != null) {
                if (start <= currentIndex && currentIndex < end) {
                    subContainers.add(elem);
                }
            } else {
                if (start <= currentIndex) {
                    subContainers.add(elem);
                }
            }

            currentIndex++;

            if (CompareUtil.compare(currentIndex, end) == 0) {
                break;
            }
        }
        return join(subContainers, conjunction);
    }

    public static <T> String join(Iterable<T> iterable, CharSequence conjunction, Integer start) {
        return join(iterable, conjunction, start, null);
    }

    /**
     * 获取容器中某个元素的的属性字段值
     *
     * @param collection
     * @param index
     * @param fieldName
     */
    public static <T, F> F getFieldValueByIndex(Collection<T> collection, int index, Func1<T, F> fieldName) {
        T t = get(collection, index);
        return EnhanceBeanUtil.getProperty(t, fieldName);
    }

    /**
     * 获取容器中第一个元素的的属性字段值
     *
     * @param collection
     * @param index
     * @param fieldName
     */
    public static <T, F> F getFieldValueByFirst(Collection<T> collection, int index, Func1<T, F> fieldName) {
        T t = getFirst(collection);
        return EnhanceBeanUtil.getProperty(t, fieldName);
    }

    /**
     * 获取容器中最后一个元素的的属性字段值
     *
     * @param collection
     * @param index
     * @param fieldName
     */
    public static <T, F> F getFieldValueByLast(Collection<T> collection, int index, Func1<T, F> fieldName) {
        T t = getLast(collection);
        return EnhanceBeanUtil.getProperty(t, fieldName);
    }


    public static void main(String[] args) {

        String json = "[[\"地区\",\"92号汽油\",\"95号汽油\",\"98号汽油\",\"0号柴油\"],[\"北京\",\"7.54\",\"8.03\",\"9.01\",\"7.24\"],[\"天津\",\"7.53\",\"7.96\",\"9.24\",\"7.20\"],[\"河北\",\"7.53\",\"7.96\",\"8.78\",\"7.20\"],[\"山西\",\"7.49\",\"8.08\",\"8.78\",\"7.26\"],[\"内蒙古\",\"7.47\",\"7.98\",\"8.75\",\"7.07\"],[\"辽宁\",\"7.51\",\"8.01\",\"8.73\",\"7.11\"],[\"吉林\",\"7.50\",\"8.09\",\"8.82\",\"7.12\"],[\"黑龙江\",\"7.50\",\"8.04\",\"9.11\",\"7.00\"],[\"上海\",\"7.50\",\"7.98\",\"8.98\",\"7.18\"],[\"江苏\",\"7.51\",\"7.99\",\"9.34\",\"7.16\"],[\"浙江\",\"7.51\",\"7.99\",\"8.75\",\"7.18\"],[\"安徽\",\"7.50\",\"8.03\",\"8.86\",\"7.23\"],[\"福建\",\"7.50\",\"8.01\",\"8.77\",\"7.19\"],[\"江西\",\"7.50\",\"8.05\",\"9.55\",\"7.25\"],[\"山东\",\"7.50\",\"8.05\",\"8.77\",\"7.11\"],[\"河南\",\"7.55\",\"8.06\",\"8.71\",\"7.18\"],[\"湖北\",\"7.55\",\"8.08\",\"9.07\",\"7.19\"],[\"湖南\",\"7.49\",\"7.96\",\"8.76\",\"7.26\"],[\"广东\",\"7.56\",\"8.19\",\"9.33\",\"7.21\"],[\"广西\",\"7.60\",\"8.21\",\"9.35\",\"7.26\"],[\"海南\",\"8.65\",\"9.19\",\"10.40\",\"7.28\"],[\"重庆\",\"7.60\",\"8.03\",\"9.05\",\"7.27\"],[\"四川\",\"7.64\",\"8.16\",\"8.87\",\"7.25\"],[\"贵州\",\"7.67\",\"8.10\",\"9.00\",\"7.30\"],[\"云南\",\"7.69\",\"8.25\",\"8.93\",\"7.27\"],[\"西藏\",\"8.42\",\"8.90\",\"9.93\",\"7.74\"],[\"陕西\",\"7.43\",\"7.85\",\"10.30\",\"7.09\"],[\"甘肃\",\"7.54\",\"8.05\",\"0.00\",\"7.10\"],[\"青海\",\"7.50\",\"8.04\",\"8.75\",\"7.12\"],[\"宁夏\",\"7.44\",\"7.86\",\"8.98\",\"7.08\"],[\"新疆\",\"7.32\",\"7.83\",\"8.75\",\"6.98\"]]";
        List<List> result = JSONUtil.toList(json, List.class);


        List<List<String>> convert = Convert.convert(new TypeReference<List<List<String>>>() {
        }, result);


        String s = tableFormat(convert);


        Console.log(s);

    }
}
